package com.shop.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.api.R;
import com.shop.common.SetMeta;
import com.shop.common.level.RightLevel;
import com.shop.entity.PermissionApi;
import com.shop.entity.Right;
import com.shop.entity.Role;
import com.shop.exception.RoleException;
import com.shop.mapper.PermissionApiMapper;
import com.shop.mapper.RightsMapper;
import com.shop.mapper.RoleMapper;
import com.shop.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service("roleService")
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RightsMapper rightsMapper;

    @Autowired
    private PermissionApiMapper permissionApiMapper;

    /**
     * 角色列表
     * @return
     */
    @Override
    public SetMeta selectRoles() {
        SetMeta setMeta = new SetMeta();

        List<Role> roles = roleMapper.selectList(null);
        List<Right> rights = rightsMapper.selectList(null);
        List<PermissionApi> permissionApis = permissionApiMapper.selectList(null);

        setChildren(roles, rights, permissionApis);

        setMeta.setSuccess(roles, "获取成功");


        return setMeta;
    }

    /**
     * 角色添加权限列表
     * @param roles
     * @param rights
     * @param permissionApis
     */
    private void setChildren(List<Role> roles, List<Right> rights, List<PermissionApi> permissionApis) {
        for (Role role : roles) {
            if (role.getPsIds() != null && !"".equals(role.getPsIds())) {
                List<Integer> psIds = Arrays.stream(role.getPsIds().split(",")).map(Integer::parseInt).collect(Collectors.toList());

                List<Right> children = new ArrayList<>();
                for (Right right : rights) {
                    if (psIds.contains(right.getId())) {
                        children.add(right);
                    }
                }

                List<Right> levelOne = setRight(children, permissionApis);

                role.setChildren(levelOne);
            }

            role.setPsCa(null);
            role.setPsIds(null);
        }
    }

    private List<Right> setRight(List<Right> children, List<PermissionApi> permissionApis) {
        List<Right> levelOne = getRightLevel(children, RightLevel.LEVEL_ONE.level, permissionApis);
        List<Right> levelTwo = getRightLevel(children, RightLevel.LEVEL_TWO.level, permissionApis);
        List<Right> levelThree = getRightLevel(children, RightLevel.LEVEL_THREE.level, permissionApis);
        merge(levelOne, levelTwo);
        merge(levelTwo, levelThree);
        return levelOne;
    }

    private List<Right> getRightLevel(List<Right> children, String level, List<PermissionApi> permissionApis) {
        List<Right> right = new ArrayList<>();
        for (Right child : children) {
            if (level.equals(child.getLevel())) {
                for (PermissionApi permissionApi : permissionApis) {
                    if (child.getId().equals(permissionApi.getPs_id())) {
                        child.setPath(permissionApi.getPs_api_path());
                    }
                }
                right.add(child);
            }
        }
        return right;
    }

    private void merge(List<Right> parents, List<Right> childrens) {
        for (Right parent : parents) {
            List<Right> child = new ArrayList<>();

            for (Right children : childrens) {
                if (parent.getId().equals(children.getPid())) {
                    child.add(children);
                }
            }
            parent.setChildren(child);
        }
    }

    /**
     * 添加角色
     * @param role
     * @return
     * @throws RoleException
     */
    @Override
    public SetMeta insertRole(Role role) throws RoleException {

        if(role.getRoleName() == null || role.getRoleName().equals("")) throw new RoleException("角色参数错误");

        int insert = roleMapper.insert(role);
        if(insert == 0) throw new RoleException("创建失败");

        SetMeta setMeta = new SetMeta();
        setMeta.setSuccess(role, "创建成功");

        return setMeta;
    }

    /**
     * 根据id查询角色
     * @param id
     * @return
     */
    @Override
    public SetMeta selectRole(Integer id){
        SetMeta setMeta = new SetMeta();

        Role role = roleMapper.selectById(id);
        if (role == null) {
            setMeta.setError("获取失败");
        } else {
            role.setPsIds(null);
            role.setPsCa(null);
            setMeta.setSuccess(role, "获取成功");
        }

        return setMeta;
    }

    /**
     * 编辑提交角色
     * @param role
     * @return
     * @throws RoleException
     */
    @Override
    public SetMeta updateRole(Role role) throws RoleException {
        if(role.getRoleName() == null || role.getRoleName().equals("")) throw new RoleException("角色参数错误");

        int update = roleMapper.update(role, Wrappers.<Role>lambdaQuery().eq(Role::getRoleId, role.getRoleId()));
        if(update == 0) throw new RoleException("修改角色失败");

        SetMeta setMeta = new SetMeta();
        setMeta.setSuccess(role, "修改角色成功");

        return setMeta;
    }

    /**
     * 删除角色
     * @param id
     * @return
     */
    @Override
    public SetMeta deleteRole(Integer id) throws RoleException {
        SetMeta setMeta = new SetMeta();
        int delete = roleMapper.delete(Wrappers.<Role>lambdaQuery().eq(Role::getRoleId, id));
        if(delete == 0) throw new RoleException("删除失败.用户不存在");
        setMeta.setSuccess(null, "删除成功");
        return setMeta;
    }

    /**
     * 删除角色指定权限
     * @param roleId
     * @param rightId
     * @return
     * @throws RoleException
     */
    @Override
    public SetMeta deleteRoleRights(Integer roleId, Integer rightId) throws RoleException {
        Role role = roleMapper.selectById(roleId);
        if (role == null) throw new RoleException("该角色不存在");

        String[] rights = role.getPsIds().split(",");
        List<Integer> psIds = Arrays.stream(rights).map(Integer::parseInt).collect(Collectors.toList());
        if(!psIds.remove(rightId)) throw new RoleException("该角色无此权限");

        List<Right> rightList = rightsMapper.selectList(Wrappers.<Right>lambdaQuery().in(Right::getId,psIds));
        List<PermissionApi> permissionApiList = permissionApiMapper.selectList(Wrappers.<PermissionApi>lambdaQuery().in(PermissionApi::getPs_id,psIds));

        List<Right> levelOne = setRight(rightList, permissionApiList);

        List<Integer> newIds = new ArrayList<>();
        List<Right> newLevel = new ArrayList<>();

        for (Right one : levelOne) {

            if (one.getChildren() != null) {
                List<Right> oneChild = new ArrayList<>();

                for (Right two : one.getChildren()) {
                    Integer sizeTwo = 0;

                    if (two.getChildren() != null) {
                        sizeTwo = two.getChildren().size();
                    }

                    if (sizeTwo != 0) {

                        for (Right child : two.getChildren()) {
                            newIds.add(child.getId());
                        }

                        oneChild.add(two);
                        newIds.add(two.getId());
                    }
                }

                if (oneChild.size() != 0) {
                    newIds.add(one.getId());
                    newLevel.add(one);
                }
            }

        }

        String psId = newIds.stream().map(Objects::toString).collect(Collectors.joining(","));
        role.setPsIds(psId);
        role.setChildren(newLevel);

        int update = roleMapper.updateById(role);
        if (update == 0) throw new RoleException("取消该权限失败");


        SetMeta setMeta = new SetMeta();
        setMeta.setSuccess(newLevel);


        return setMeta;
    }

    /**
     * 角色授权
     * @param roleId
     * @param role
     * @return
     */
    @Override
    public SetMeta rightsToRole(Integer roleId, Role role){
        SetMeta setMeta = new SetMeta();

        role.setRoleId(roleId);
        int update = roleMapper.update(role, Wrappers.<Role>lambdaQuery().eq(Role::getRoleId, role.getRoleId()));
        if (update == 0) {
            setMeta.setError("该用户不存在");
        } else {
            setMeta.setSuccess("更新成功");
        }

        return setMeta;
    }


}
